<template>
	<view class="content">
		<!-- 毛玻璃背景 -->
		<view class="back-filter" />
		<!-- 头像 -->
		<view class="head-img">
			<image :class="amcls" src="/static/jie.jpg" mode="aspectFill" />
			<view class="name">小杰助手</view>
		</view>
		<!-- 文本回写 -->
		<view class="chat-view">
			<text>{{ chatText }}</text>
		</view>
		<!-- 组件 -->
		<view class="voice-btn-wrap">
			<nb-voice-record @startRecord="start" @endRecord="end" @cancelRecord="cancel" />
			</nb-voice-record>
		</view>
	</view>
</template>

<script>
import base64Utils from './base64.js'
export default {
	data() {
		return {
			amcls: '',
			content: '',
			chatText: '请长按开始讲话',
			// 这里换成自己的
			asrUrl: 'http://xxx/paddlespeech/asr',
			rasaUrl: 'http://xxx/webhooks/rest/webhook',
			ttsUrl: 'http://xxx/paddlespeech/tts'
		} 
	},
	onLoad() {
		
	},
	methods: {
		start() {
			this.amcls = 'am5s'
		},
		end(e) {
			let path = e.tempFilePath
			this.amcls = 'am1s'
			base64Utils.pathToBase64(path).then(base64 => {
				this.request(this.asrUrl, {
					audio: base64.split(',')[1],
					audio_format: 'mp3',
					sample_rate: 16000,
					lang: 'zh_cn',
					punc: 0
				}).then(res => {
					let rs = res[1]
					if (rs['statusCode'] == 200 && rs['data']['code'] == 200) {
						let rsTxt = rs['data']['result']['transcription']
						this.printText('我：' + rsTxt, () => {
							this.requestRasa(rsTxt)
						})
					} else {
						this.setError()
					}
				}).catch(this.setError)
			}).catch(this.setError)
		},
		// play 
		playText(text) {
			this.request(this.ttsUrl, { text }).then(res => {
				let rs = res[1]
				if (rs['statusCode'] == 200 && rs['data']['code'] == 200) {
					const rsTxt = 'data:audio/wav;base64,' + rs['data']['result']['audio']
					const audioContext = uni.createInnerAudioContext()
					base64Utils.base64ToPath(rsTxt).then(path => {
						audioContext.src = path
						audioContext.play()
					})
				}
			})
		},
		// 请求rasa
		requestRasa(text) {
			this.request(this.rasaUrl, {
				sender: 'sender',
				message: text
			}).then(res => {
				let rs = res[1]
				if (rs['statusCode'] == 200) {
					let rsd = rs['data'][0]
					this.printText('小杰：' + rsd['text'])
					this.playText(rsd['text'])
				} else {
					this.setError()
				}
				this.amcls = ''
			}).catch(this.setError)
		},
		// 错误
		setError() {
			this.chatText = '出现错误！！'
			this.amcls = ''
		},
		// 取消
		cancel() {
			this.amcls = ''
		},
		// 请求
		request(url, data) {
			return uni.request({
				url,
				header: {
					'Content-Type': 'application/json;charset=utf-8;'
				},
				method: 'POST',
				data
			})
		},
		printText(content, cb) {
			this.chatText = ''
			// 声明一个变量，用来监听要分割的长度
			var wenlen = 0
			this.timer = setInterval (()=>{
				// 取到content的第wenlen位
				this.chatText = content.substr(0,wenlen)
				// wenlen大于content的长度，停止计时器
				if (wenlen < content.length) {
					wenlen++
				} else {
					clearInterval(this.timer)
					// return
					cb && cb()
				}
			}, 100)
		}
	}
};
</script>

<style scoped lang="scss">
.content {
	position: relative;
	height: 100vh;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	background-image: url('/static/back.jpg');
	background-size: cover;
	background-position: center;
}

.back-filter {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background-color: rgba(255, 255, 255, 0.2);
	backdrop-filter: blur(30px) saturate(200%);
	z-index: 10;
}

.voice-btn-wrap {
	width: 100%;
	position: fixed;
	bottom: 200rpx;
	left: 0;
	display: flex;
	justify-content: center;
	z-index: 20;
}

.head-img {
	z-index: 30;
	text-align: center;
	margin-top: -480upx;
	image {
		width: 250upx;
		height: 250upx;
		border-radius: 50%;
		box-shadow: 2upx 3upx 4upx #434343;
	}
	.name {
		color: #f1f1f1;
		padding-top: 30upx;
		font-size: 40upx;
		text-shadow: 2upx 3upx 4upx #202020;
	}
}

.chat-view {
	z-index: 50;
	margin-top: 60upx;
	padding: 20upx 30upx;
	background-color: rgba(0, 0, 0, .2);
	border-radius: 8upx;
	min-height: 46upx;
	max-width: 500upx;
	
	text {
		text-align: center;
		color: #f9f9f9;
	}
}

.am5s {
	animation: spin 5s linear infinite;  
}

.am1s {
	animation: spin 1s linear infinite;  
}

@keyframes spin {  
  from {  
    transform: rotate(0deg);  
  }  
  to {  
    transform: rotate(360deg);  
  }  
}  
</style>
